from querier.esquerier import ElasticSearchQuerier
import querier.weibo.utils as utils
import math


class WeiboPostMatchQuerier(ElasticSearchQuerier):
    def __init__(self, es, index, doc_type, nlp_service):
        super(WeiboPostMatchQuerier, self).__init__(es, index, doc_type)
        self.nlp_service = nlp_service

    def _build_query(self, args):
        user_id = args.get('user_id', None)
        if user_id is None:
            raise ValueError('"user_id" is needed.')
        term = args.get('term', '')
        filters = args.get('filters', {})
        order = args.get('order_by', utils.ORDER_OVERALL)
        from_ = args.get('from', 0)
        size_ = args.get('size', 10)
        highlight = args.get('highlight', False)

        # 处理查询文本
        term2, keywords = utils.process_query_term(term, self.nlp_service)
        query = self._genQuery(user_id, term, filters, order, from_, size_, highlight)
        return query, {}, {'keywords': keywords, 'order': order}

    def _build_result(self, es_result, param):
        keywords = param['keywords']
        order = param['order']
        total = es_result['hits']['total']
        posts = []
        for hit in es_result['hits']['hits']:
            posts.append(extractResult(hit, order))
        return {
            'total': total,
            'keywords': keywords,
            'posts': posts
        }

    def _genQuery(self, user_id, query_keywords, filters, order, from_, size_, highlight):
        must_clause = []
        if query_keywords:
            must_clause.append(
                    {
                        'query_string': {
                            'query': query_keywords,
                            'fields': ['weibo_text',  'keywords', 'r_weibo_text'],
                            'minimum_should_match': utils.MINIMUM_SHOULD_MATCH
                        }
                    }
            )

        query = {'query': {
            'bool': {
                'must': must_clause,
                'filter': {'term': {'user_id': user_id}}
            }
        }, 'sort': [
            '_score',
            {'publish_timestamp': 'desc'},
            {'sum_engagement': 'desc'},
        ], 'from': from_, 'size': size_}

        if highlight:
            query['highlight'] = {
                "pre_tags": ["<span class='keyword'>"],
                "post_tags": ["</span>"],
                "fields": {"keywords": {}, "weibo_text": {}, "r_weibo_text": {}}
            }

        return query


def extractResult(hit, order):
    source_ = hit['_source']
    score_ = hit['_score']
    res = utils.extract_post_from_source(source_)
    post_influence = math.log10(res['sum_engagement'] + 1) * 158
    if order == utils.ORDER_RELATIVE:
        post_relative = score_
    elif order == utils.ORDER_INFLUENCE:
        post_relative = score_
    else:
        post_relative = score_ / math.log10(post_influence + 2)

    highlight = hit.get('highlight')
    if highlight:
        weibo_text = highlight.get('weibo_text', [''])[0]
        r_weibo_text = highlight.get('r_weibo_text', [''])[0]
        summary = weibo_text
        if r_weibo_text:
            summary += '//' + r_weibo_text
        res['summary'] = summary
        if highlight.get('keywords'):
            res['keywords'] = highlight.get('keywords')[0]


    # normalize post_relative
    post_relative = math.log2(1 + post_relative)
    post_relative = min(1, post_relative)

    res['score'] = post_influence
    res['relative'] = post_relative

    return res

